package com.gitee.feizns.quickstart.mybatis.plus.handler.type;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.TypeHandler;

/**
 * 使用{@link ObjectMapper}复杂泛型JSON转换类
 * <p>
 *     mybatis plus对实体中的字段的复杂泛型支持<br/>
 *     对于泛型中是自定义的类型时：使用通过继承该接口来实现对应属性的的类型转换支持
 * </p>
 * <p>
 *     首先自定义一个{@link TypeHandler}<br/>
 * </p>
 * <pre>{@code public class PersonListTypeHandler extends JacksonGenericTypeHandler<List<Person>> {}}</pre>
 * <p>
 *     再配置实体类时指定{@link TableName#autoResultMap()}的同时配置{@link TableField#typeHandler()}<br/>
 * </p>
 * <pre class="code">
 * &#064;TableName(autoResultMap = true)
 * public class User {
 *     &#064;TableField(typeHandler=PersonListTypeHandler.class)
 *     private List<Person> persons;
 * }
 * </pre>
 * @param <T> （字段类型引用）通过继承该类来实现对泛型类型的处理
 * @see TypeReference
 * @see TypeHandler
 * @author feizns
 * @since 2023/2/27
 */
public class JacksonGenericTypeHandler<T> extends TypeReference<T> implements JsonTypeHandler<T> {

    private static ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public String toJson(Object object) {
        try {
            return OBJECT_MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public T parse(String json) {
        try {
            return json != null ? OBJECT_MAPPER.readValue(json, this) : null;
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static void setObjectMapper(ObjectMapper objectMapper) {
        OBJECT_MAPPER = objectMapper;
    }

}
